#include "StdAfx.h"
#include "Connection.h"

using namespace seven;


Connection::Connection( QObject *parent,QTcpSocket * socket )
	: QObject(parent)
{
	SetSocket(socket);	
}

Connection::Connection( QObject *parent ): QObject(parent)
{
	SetSocket(NULL);
}

Connection::~Connection()
{
	//Abort();
}

void Connection::displayError( QAbstractSocket::SocketError socketError )
{
	QString str;
	switch (socketError) {	
	case QAbstractSocket::RemoteHostClosedError:
		str = "RemoteHostClosedError";
		break;
	case QAbstractSocket::HostNotFoundError:
		str =("The host was not found. Please check the host name and port settings.");
		break;
	case QAbstractSocket::ConnectionRefusedError:
		str =("The connection was refused by the peer. \
			  Make sure the fortune server is running, \
			  and check that the host name and port \
			  settings are correct.");
		break;
	default:
		str = (tcpSocket->errorString());
	}

	Show(str);
}

void Connection::readMessage()
{
	GOOGLE_PROTOBUF_VERIFY_VERSION;

	if (!tcpSocket)
	{
		return;
	}

	QDataStream in(tcpSocket);
	in.setVersion(QDataStream::Qt_4_0);

	while (1)
	{
		if (messageSize == 0) 
		{
			int bytes = tcpSocket->bytesAvailable();
			if (tcpSocket->bytesAvailable() < (int)sizeof(quint64))
				return;
			in >> messageSize;
		}

		if (tcpSocket->bytesAvailable() < messageSize)
			return;

		char* buff = new char[messageSize];
		in.readRawData(buff,messageSize);

		seven::TransferMessage message;
		message.ParseFromArray(buff,messageSize);

		emit revMsg(message);
		messageSize = 0;
		delete []buff;
	}

}

void Connection::Abort()
{
	if(tcpSocket)
	{	
		tcpSocket->abort();
		messageSize = 0;
	}
}

bool Connection::SendMsg( const seven::TransferMessage& msg )
{
	if (!tcpSocket)
	{
		return false;
	}

	std::string block = msg.SerializeAsString();
	quint64 blockSize = block.size();

	QByteArray blockHeader;
	QDataStream out(&blockHeader, QIODevice::WriteOnly);
	out.setVersion(QDataStream::Qt_4_0);
	out<<blockSize;
	tcpSocket->write(blockHeader);
	tcpSocket->write(block.data(),block.size());

	return true;
}

bool Connection::SendMsg( const seven::MessageType& msgType )
{
	TransferMessage msg;
	msg.set_message_type(msgType);
	return SendMsg(msg);
}

void Connection::SetSocket( QTcpSocket* socket )
{
	if (tcpSocket!=socket && socket)
	{
		tcpSocket = socket;
		messageSize = 0;
		connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readMessage()));
		connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
		connect(tcpSocket, SIGNAL(disconnected()),tcpSocket, SLOT(deleteLater()));
	}
}

void Connection::Disconnect()
{
	if (tcpSocket && tcpSocket->isValid())
	{
		tcpSocket->disconnectFromHost();
		messageSize = 0;
	}
}

